from tkinter import *
import sys
import socket


class Vue():
    def __init__(self, parent):
        self.master = Tk()
        self.parent = parent
        self.afficherLogin()
        
        frameCourant = "rien"
        self.master.protocol("WM_DELETE_WINDOW", self.retirerDeLaListe)
     
    def pressEnterLogin(self, event):
         self.parent.validerLogin()
       
    def afficherLogin(self):
        self.frameLogin = Frame(self.master, width=400, height=400)
        self.frameLogin.pack()
        self.frameCourant = self.frameLogin
        self.frameLogin.bind_all("<Return>", lambda e: self.parent.validerLogin(self.entIP.get(), self.entNom.get(), self.entMdp.get()))
        
        self.etiqNom = Label(self.frameLogin, text="Nom d'utilisateur")
        self.etiqNom.pack()
    
        self.entNom = Entry(self.frameLogin)
        self.entNom.insert(0, "Adam")
        self.entNom.pack()
        self.entNom.focus() #Donne le focus au champ pour entrer le nom
        
        self.etiqMdp = Label(self.frameLogin, text="Mot de passe")
        self.etiqMdp.pack()
        
        self.entMdp = Entry(self.frameLogin)
        self.entMdp.insert(0, "Smith")
        self.entMdp.pack()
        
        self.etiqIP = Label(self.frameLogin, text="Adresse IP")
        self.etiqIP.pack()
        
        self.entIP = Entry(self.frameLogin)
        self.entIP.insert(0, self.parent.getMyIp())
        self.entIP.pack()
        
        #Lambda utilise pour pouvoir passer des parametres a la fonction
        self.bouton = Button(self.frameLogin, text="Ok", command=lambda:self.parent.validerLogin(self.entIP.get(), self.entNom.get(), self.entMdp.get()))
        self.bouton.pack()
            
    
    #Methode qui va construire la listbox de la salle d'attente
    def miseAJours(self):
        self.listbox.delete(0, END)
        self.listeJoueurs = self.parent.creeListeJoueurs()
        joueurDansLaListe = False
        self.item = 0
        
        #On affiche le nombre de joueur dans la liste
        if len(self.listeJoueurs) == 1:
            self.etiqNb.config(text=str(len(self.listeJoueurs)) + " joueur dans le lobby")
            self.etiqNb.grid(row=2, column=0)
        
        else:
            self.etiqNb.config(text=str(len(self.listeJoueurs)) + " joueurs dans le lobby")
            self.etiqNb.grid(row=2, column=0)
            
        #on regarde si le joueur est encore dans la liste
        for nom in self.listeJoueurs:
            if nom == self.parent.modele.joueur:
                joueurDansLaListe = True
        
        if joueurDansLaListe:
            for joueur in self.listeJoueurs:
                self.listbox.insert(END, joueur)
                if joueur != self.parent.getJoueurCourant():
                    self.item += 1
                else:
                    self.listbox.itemconfig(self.listeJoueurs.index(joueur), {'bg':'black', 'fg':'white'})
                

        #La liste est mise a jour toutes les 50 millisecondes au cas ou un joueur se deconnecte
        self.master.after(50, self.miseAJours)

    def insererTexteChat(self):
        self.parent.insererTexteChat(self.parent.modele.joueur, self.entreChat.get())
        self.entreChat.delete(0, END)

    def raffraichirChat(self):
        self.leTexte = ""
        self.listeChat = self.parent.creeListeChat()
        self.textChat.delete(1.0, END)
        
        for texte in self.listeChat:
            self.leTexte += texte + "\n"
            
        self.textChat.insert(END, self.leTexte)
        self.textChat.see(END)
          
        self.leTexte = ""

        self.textChat.after(50, self.raffraichirChat)
        
    
    def pressEnterChat(self, event):
        self.insererTexteChat()
        self.raffraichirChat()
    
    def debuterPartie(self):
        self.parent.envoiDebutPartie()
               
        
    def afficherSalle(self):
        self.frameSalle = Frame(self.master, width=800, height=600)
        self.changerFrame(self.frameSalle)
        self.frameSalle.pack_propagate(0)
        
        self.frameSalle.bind_all("<Return>", self.pressEnterChat)
        
        self.etiqSalle = Label(self.frameSalle, text="Lobby")
        self.etiqSalle.grid(row=0, column=0)
        
        self.listbox = Listbox(self.frameSalle)
        self.listbox.grid(row=1, column=0)
        
        self.etiqNb = Label(self.frameSalle)
        self.etiqNb.grid(row=2, column=0)
        
        self.etiqChat = Label(self.frameSalle, text="Chat")
        self.etiqChat.grid(row=0, column=3)
        
        self.textChat = Text(self.frameSalle, width=100)
        self.textChat.grid(row=1, column=4, columnspan=4)
        
        self.boutonChat = Button(self.frameSalle, text="Envoyer", command=self.insererTexteChat)
        self.boutonChat.grid(row=3, column=5, sticky=W)
        
        if self.parent.getJoueurCourant() == self.parent.getCreateurPartie():
            self.boutonDebutPartie = Button(self.frameSalle, text="Debuter la partie", command=self.debuterPartie)
            self.boutonDebutPartie.grid(row=3, column=6, sticky=W)
        
        self.entreChat = Entry(self.frameSalle, width=50)
        self.entreChat.grid(row=3, column=4, sticky=W)
        self.entreChat.focus()
        
        self.etiqAIp = Label(self.frameSalle, text="IP du serveur : " + self.parent.getIpServeur())
        self.etiqAIp.grid(row=3, column=0)
        
        self.miseAJours()
        self.raffraichirChat()
        
    def changerFrame(self, leFrame):
        self.frameCourant.pack_forget()
        self.frameCourant = leFrame
        leFrame.pack()
    
    def retirerDeLaListe(self): #J'ai ajoute l'exception pour qu'on puisse quitter meme si le joueur n'existait pas dans la liste
        try:
            self.parent.retirerDeLaListe(self.parent.modele.joueur)
        except:
            print("Il n'y avait pas de joueur a enlever de la liste de joueurs")
        finally:
            self.master.destroy()
            sys.exit()
            raise SystemExit
        
    def afficherPartie(self):
        width = 800
        height = 600
        worldWidth = 1000
        worldHeight = 1000
        
        self.minimap = Minimap()
        self.frameJeu = Frame(self.master, width=width, height=height, background="red")
        self.changerFrame(self.frameJeu)
        self.canvas = Interface(self, self.frameJeu, width=width, height=(height - 200), worldWidth=worldWidth, worldHeight=worldHeight)
        self.hud = Hud(self, self.frameJeu, width=width, height=(height - 400), worldWidth=worldWidth, worldHeight=worldHeight) 
        self.canvas.redraw()
        self.hud.redraw()  

class Minimap():
    def __init__(self, posX=0, posY=0, tag="minimap"):
        self.posX = posX
        self.posY = posY

class Interface():
    def __init__(self, parent, frame, width=800, height=400, worldWidth=1000, worldHeight=1000):
        self.parent = parent
        self.frame = frame
        self.canvas = Canvas(self.frame, scrollregion=(0, 0, worldWidth, worldHeight), width=width, height=height)
        self.canvas.pack()
        self.canvas.bind("<Button-1>", self.selection)
        self.canvas.bind("<Button-3>", self.action)
        self.canvas.bind("<Left>", self.scroll)
        self.canvas.bind("<Right>", self.scroll)
        self.canvas.bind("<Up>", self.scroll)
        self.canvas.bind("<Down>", self.scroll)
        self.canvas.bind("<Motion>", self.infoMouseOver)
        self.canvas.focus_set()
        self.canvas.configure(yscrollincrement='1')
        self.canvas.configure(xscrollincrement='1')
        self.offsetX = 0
        self.offsetY = 0
        self.offsetXMax = worldWidth - width
        self.offsetYMax = worldHeight - height
        self.uniteCourrante = []
        
    def scroll(self, event):
        if(event.keysym == "Right"):
            event.widget.xview_scroll(10, UNITS)
            if(self.offsetX < self.offsetXMax):
                self.offsetX += 10
                self.parent.minimap.posX += 1
                #self.parent.hud.redraw()
                print(self.offsetX)
        elif(event.keysym == "Left"):
            event.widget.xview_scroll(-10, UNITS)
            if(self.offsetX > 0):
                self.offsetX -= 10
                self.parent.minimap.posX -= 1
                #self.parent.hud.redraw()
                print(self.offsetX)
        elif(event.keysym == "Up"):
            event.widget.yview_scroll(-10, UNITS)
            if(self.offsetY > 0):
                self.offsetY -= 10
                self.parent.minimap.posY -= 1
                #self.parent.hud.redraw()
                print(self.offsetY)
        elif(event.keysym == "Down"):
            event.widget.yview_scroll(10, UNITS)
            if(self.offsetY < self.offsetYMax):
                self.offsetY += 10
                self.parent.minimap.posY += 1
                #self.parent.hud.redraw()
                print(self.offsetY)
        else:
            print("ohgod")
            
    def selection(self, event): #Selectionne une unite/objet bidon sur le canvas
        trouve = 0
        infoSelection = ""
        if(trouve == 0):
            for objet in self.parent.parent.modele.joueur.emplacement.listeEntites:
                if(objet.selection((event.x + self.offsetX), (event.y + self.offsetY)) == 1):
                    self.uniteCourrante = [objet.nom, objet.id]
                    infoSelection += "Unite selectionne: "
                    infoSelection += objet.nom
                    print(objet.nom)
                    trouve = 1
                    break
                else:
                    self.uniteCourrante = ""
        print("X Vue:")   
        print(int(event.x / 10 + self.offsetX / 10))
        print("Y Vue:")  
        print(int(event.y / 10 + self.offsetY / 10))
        print(self.parent.parent.modele.joueur.emplacement.ressourceTerrainSelectionne(int(event.x / 10 + self.offsetX / 10), int(event.y / 10 + self.offsetY / 10)))
        self.parent.hud.infoSelection.config(text=infoSelection)    
        #self.redraw()
        
    def action(self, event): #Bouge l'unite/objet bidon selectionnee
        print(event.x + self.offsetX, event.y + self.offsetY)
        
        if(len(self.uniteCourrante) == 0):
            print("")
        elif(self.uniteCourrante[0] == "Tank"):
            self.parent.parent.modele.joueur.emplacement.listeEntites[self.uniteCourrante[1]].posX = self.parent.parent.modele.joueur.emplacement.listeEntites[self.uniteCourrante[1]].deplacement(event.x + self.offsetX, event.y + self.offsetY, 0)[4]
            self.parent.parent.modele.joueur.emplacement.listeEntites[self.uniteCourrante[1]].posY = self.parent.parent.modele.joueur.emplacement.listeEntites[self.uniteCourrante[1]].deplacement(event.x + self.offsetX, event.y + self.offsetY, 0)[5]
            
    def redraw(self): #Redessine le canvas; plus utile que de bouger les objets sur le canvas!!
        self.canvas.delete(ALL)
        #self.parent.hud.redraw()
        
        for ressource in self.parent.parent.modele.joueur.emplacement.listeRessources:
            if ressource.type == "fer":
                self.canvas.create_rectangle(ressource.posX * 10, ressource.posY * 10, ressource.posX * 10 + ressource.size, ressource.posY * 10 + ressource.size, fill="green")
            elif ressource.type == "petrole":
                self.canvas.create_rectangle(ressource.posX * 10, ressource.posY * 10, ressource.posX * 10 + ressource.size, ressource.posY * 10 + ressource.size, fill="gray")
            elif ressource.type == "titane":
                self.canvas.create_rectangle(ressource.posX * 10, ressource.posY * 10, ressource.posX * 10 + ressource.size, ressource.posY * 10 + ressource.size, fill="red")
                
        for objet in self.parent.parent.modele.joueur.emplacement.listeEntites: #Liste d'objets bidons (futurs unites)
            if len(self.uniteCourrante) != 0 and objet.id == self.uniteCourrante[1]:
                self.canvas.create_rectangle(objet.posX, objet.posY, objet.posX + objet.dimX, objet.posY + objet.dimY, fill="red")
            else:
                self.canvas.create_rectangle(objet.posX, objet.posY, objet.posX + objet.dimX, objet.posY + objet.dimY, fill="blue")
        self.frame.after(30, self.redraw)
        
    def infoMouseOver(self, event): #Envoi les infos des objets sous le curseur au HUD
        infoRes = ""
        infoUnit = ""
        
        if(self.parent.parent.modele.joueur.emplacement.ressourceTerrainSelectionne(int(event.x / 10 + self.offsetX / 10), int(event.y / 10 + self.offsetY / 10)) != None and self.parent.parent.modele.joueur.emplacement.ressourceTerrainSelectionne(int(event.x + self.offsetX), int(event.y + self.offsetY) != "")):
            infoRes += "Ressource: "
            infoRes += self.parent.parent.modele.joueur.emplacement.ressourceTerrainSelectionne(int(event.x / 10 + self.offsetX / 10), int(event.y / 10 + self.offsetY / 10))
            
        for objet in self.parent.parent.modele.joueur.emplacement.listeEntites:
                if(objet.selection((event.x + self.offsetX), (event.y + self.offsetY)) == 1):
                    infoUnit += "Unite: "
                    infoUnit += objet.nom
                    break
                
        self.parent.hud.infoRes.config(text=infoRes)
        self.parent.hud.infoUnit.config(text=infoUnit)


class Hud():
    def __init__(self, parent, frame, width=800, height=200, worldWidth=1000, worldHeight=1000):
        self.parent = parent
        self.frame = Frame(frame, width=width, height=height, background="black")
        self.frame.pack(fill=BOTH)
        self.canvas = Canvas(self.frame, width=100, height=100)
        self.canvas.pack(side=LEFT)
        self.hint = Label(self.frame, text="Les fleches du clavier font scroller la vue.", fg="white", bg="black")
        self.hint.pack()
        self.infoRes = Label(self.frame, fg="white", bg="black")
        self.infoRes.pack()
        self.infoUnit = Label(self.frame, fg="white", bg="black")
        self.infoUnit.pack()
        self.infoSelection = Label(self.frame, fg="white", bg="black")
        self.infoSelection.pack()
        self.worldWidth = worldWidth
        self.worldHeight = worldHeight
    def redraw(self):
        self.canvas.delete(ALL)
        self.canvas.create_rectangle(self.parent.minimap.posX, self.parent.minimap.posY, (self.parent.minimap.posX + 80), (self.parent.minimap.posY + 40), outline="brown")
        
        for ressource in self.parent.parent.modele.joueur.emplacement.listeRessources:
            self.canvas.create_rectangle((ressource.posX) - 1, (ressource.posY) - 1, (ressource.posX) + 1, (ressource.posY) + 1, fill="green")
            
        for objet in self.parent.parent.modele.joueur.emplacement.listeEntites: #Liste d'objets bidons (futurs unités)
            if len(self.parent.canvas.uniteCourrante) != 0 and objet.id == self.parent.canvas.uniteCourrante[1]:
                self.canvas.create_rectangle((objet.posX / 10) - 2, (objet.posY / 10) - 2, (objet.posX / 10) + 2, (objet.posY / 10) + 2, fill="red")
            else:
                self.canvas.create_rectangle((objet.posX / 10) - 2, (objet.posY / 10) - 2, (objet.posX / 10) + 2, (objet.posY / 10) + 2, fill="blue")
        self.frame.after(30, self.redraw)#self.hud.redraw() 